Unity データを型指定無しResources非経由で楽に読み込むのを探求する


概要

例えばプラグイン作っていたとして。以下の条件を考えたいとする。

1.Editorで作ったデータ(string)をEditor以外、例えばスマフォ上で動くClientでも使いたい

2.UnityEditor外でもヒューマンリーダブルにしたいのでassetは使いたくない(手、テキストエディタとかでも編集したいしサーバ上でも内容確認したい)

3.Resourcesフォルダ作ってテキストとか置くのヤだ(TextAssetの拒否)

4.通信したくない

5.そのファイルが無くてもコンパイルが通るようにしたい

となるとどんな方法が使えるのか?

最終的には全ての条件を満たすものができた。



コードからScriptableObjectのコードを生成して使用する

ScriptableObjectをInstantiateするのは、Clientからでもできる。


usage:

var scriptableObj = (ScriptableObjectClass)ScriptableObject.CreateInstance("ScriptableObjectClass");



ScriptableObjectClass.js

#pragma strict


class ScriptableObjectClass extends ScriptableObject {

}


サンプルがjsであることに特に意味はない。

usageのような書き方で使用できる。


んで、ScriptableObject のインスタンスから hello というstringを得るコードを考えると、usageとScriptableObjectClass.jsはこんな感じになる。



usage:

var scriptableObj = (ScriptableObjectClass)ScriptableObject.CreateInstance("ScriptableObjectClass");

var result = scriptableObj.GetHello();// = “hello”



ScriptableObjectClass.js

#pragma strict


class ScriptableObjectClass extends ScriptableObject {

public function GetHello () {

return "hello";

}

}


ここまでだと、要件の1~4は満たせる。

1.コンパイルされるコードなので、コードがEditorフォルダ外にさえあればどこからでも使える。

2.所詮テキストなのでヒューマンリーダブル。

3.Resourcesフォルダの世話にはなっていない。

4.通信してない。


が、5が満たせない。

5.そのファイルが無くてもコンパイルが通るようにしたい

usageの中にScriptableObjectを継承したクラス名 ScriptableObjectClass の指定があり、そのせいで「このクラスが存在していないとコンパイルが通らない」。



ファイルが無くてもコンパイルが通るようにしたい

キャストがあるんで型情報が無いとダメ、、って感じなので、とても普通。

partialを使っても同じシグニチャのメソッドは複数定義できないのでダメ。


で、それについて悩んでみたら、よく考えたらScriptableObject、基礎としてToStringメソッド持ってるので、

ToStringメソッドをオーバーライドすると型指定しないでも目的の値を返せていいな~みたいなことに気づいた。


ScriptableObjectClass.js

#pragma strict


class ScriptableObjectClass extends ScriptableObject {

public function ToString () {

return "そして殺す";

}

}

で、この書き方をすると、usageから型のキャストが消せるので、

その型が存在して無くてもコンパイルが通るようになる。


usage:

var scriptableObj = ScriptableObject.CreateInstance("ScriptableObjectClass”);// キャスト消えたな。つまりその型のファイルが無くてもコンパイル通る。

var result = scriptableObj.ToString();// = “そして殺す”


感想

5.そのファイルが無くてもコンパイル通る、のせいでいろいろ面倒な感じ。

そのファイルがなかった場合はエラー、というフローが本来は必要。実際の対応はアサーションとかで殴るとかか。

後から読むとヒントがCreateInstanceメソッドの引数くらいしかないのも減点ポイント。(まあ十分だとは思うけど。)


データソースとしてのヒューマンリーダブルさを求めつつResourcesを拒否するとこうなった。

ひどいことになってると思うので別解を求む。


とおもったら、ScriptableObjectを継承したクラスをでっち上げて、そっちは常にある、みたいな構造がつくれればいいな。